//
//  TimedEvent.swift
//  Utility
//
//  Created by 何海涛 on 2017/5/24.
//  Copyright © 2017年 何海涛. All rights reserved.
//

import Foundation

open class PickerTools {
    
    fileprivate static weak var pickerView: UIPickerView?
    
    static public func reloadPickerView() {
        pickerView?.reloadAllComponents()
    }
    

    static public func selectByPickerActionSheet<T>(_ data: [T], display: @escaping (_: T) -> String, enableDynamicFont: Bool = false, defaultSelectRow : ((_:T)->Bool)? = nil, selectAction: @escaping (_: T) -> Void, customViewDisplay: ((T, UIFont) -> UIView)? = nil, viewInitalizer : (()->PickerActionSheetView<T>)? = nil) {
        let pickerView = viewInitalizer == nil ? PickerActionSheetView<T>() : viewInitalizer!()
        pickerView.frame = CGRect(x: 0, y: 0, width: CommonDefine.kScreenWidth, height: 236)
        pickerView.backgroundColor = UIColor.white
        pickerView.data = data
        pickerView.display = display
        pickerView.customViewDisplay = customViewDisplay
        pickerView.dynamicFontSizeEnabled = enableDynamicFont
        
        let actionSheet = GAActionSheet()
        actionSheet.contentView = pickerView
        actionSheet.show()
        pickerView.window?.endEditing(true)
        
        let weakRefer = WeakReferenceWrapper(refer: actionSheet)
        func cancelButtonAction() {
            if let sheet: GAActionSheet = weakRefer.refer() {
                sheet.dismiss()
            }
        }
        pickerView.cancelButtonAction = cancelButtonAction
        pickerView.confirmButtonAction = selectAction
        pickerView.render()
        pickerView.setDefaultValue(defaultSelectRow)
        
        self.pickerView = pickerView.pickerView
    }
    
    
    
    open class EmptyPickActionSheetView<T>: UIView {
        public init() {
            super.init(frame: CGRect.zero)
        }
        
        required public init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        var cancelButton = UIButton()
        open var cancelButtonAction: ( () -> Void)?
        @objc open func runCancelButtonAction() {
            cancelButtonAction?()
        }
        
        var confirmButton = UIButton()
        var confirmButtonAction: ((_: T) -> Void)?
        
        open var pickedValue : T?
        @objc open func runConfirmButtonAction() {
            #if DEBUG
                print("runConfirmButtonAction: pickedValue")
                print(pickedValue as Any)
            #endif
            if pickedValue != nil {
                confirmButtonAction?(pickedValue!)
            }
            runCancelButtonAction()
        }
        
        open func render() {
            
            cancelButton.removeFromSuperview()
            cancelButton.frame = CGRect(x: 0, y: self.frame.height - 50, width: ViewHelper.screenWidth() / 2, height: 50)
            cancelButton.setTitle(NSLocalizedString("取消", comment: "./PMS/Classes/Extension/ActionSheetPicker/CommonFunctions.swift"), for: UIControl.State())
            cancelButton.titleLabel?.font = UIFont.systemFont(ofSize: 16)
            cancelButton.setTitleColor(CommonColors.c_aaaaaa, for: UIControl.State())
            cancelButton.setBackgroundColor(CommonColors.c_e5e5e5, forState: .highlighted)
            cancelButton.addTarget(self, action: #selector(EmptyPickActionSheetView.runCancelButtonAction), for: .touchUpInside)
            self.addSubview(cancelButton)
            
            confirmButton.removeFromSuperview()
            confirmButton.frame = CGRect(x: ViewHelper.screenWidth() / 2, y: self.frame.height - 50, width: ViewHelper.screenWidth() / 2, height: 50)
            confirmButton.setTitle(NSLocalizedString("确定", comment: "./PMS/Classes/Extension/ActionSheetPicker/CommonFunctions.swift"), for: UIControl.State())
            confirmButton.titleLabel?.font = UIFont.systemFont(ofSize: 16)
            confirmButton.setTitleColor(CommonColors.c_536dfe, for: UIControl.State())
            confirmButton.setBackgroundColor(CommonColors.c_e5e5e5, forState: .highlighted)
            confirmButton.addTarget(self, action: #selector(EmptyPickActionSheetView.runConfirmButtonAction), for: .touchUpInside)
            self.addSubview(confirmButton)
            
            let separator1 = UIView()
            let separator2 = UIView()
            separator1.frame = CGRect(x: 0, y: self.frame.height - 50, width: ViewHelper.screenWidth(), height: CommonDefine.kPixel)
            separator1.backgroundColor = CommonColors.c_c2c2c2
            self.addSubview(separator1)
            separator2.frame = CGRect(x: ViewHelper.screenWidth() / 2, y: self.frame.height - 50, width: CommonDefine.kPixel, height: 50)
            separator2.backgroundColor = CommonColors.c_c2c2c2
            self.addSubview(separator2)
        }
    }
    
    open class PickerActionSheetView<T>: EmptyPickActionSheetView<T>, UIPickerViewDataSource, UIPickerViewDelegate {
        
        var pickerView = UIPickerView()
        var data = Array<T>()
        var display: (_: T) -> String = { x in x as? String ?? "" }
        var pickerContainer = UIView()
        var customViewDisplay: ((T,UIFont) -> UIView)?
        
        var itemFontSize = VS.font16
        var dynamicFontSizeEnabled = false
        var dynamicFontSizes = [VS.font16, VS.font14, VS.font12]
        
        public func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
        public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return data.count
            
        }
        public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            return display(data[row])
        }
        
        public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            if row < data.count {
                self.pickedValue = data[row]
            }
        }
        
        public func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
            return 35
        }
        
        public func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
            if let customViewDisplay = customViewDisplay {
                return customViewDisplay(data[row], itemFontSize)
            }
            let label = UILabel()
            label.font = itemFontSize
            label.text = display(data[row])
            label.textAlignment = .center
            label.lineBreakMode = .byTruncatingMiddle
            return label
        }
        
        override open func render() {
            super.render()
            
            // item font size
            if dynamicFontSizeEnabled {
                var maxLengthItem = ""
                for item in self.data {
                    let str = self.display(item)
                    if str.length > maxLengthItem.length {
                        maxLengthItem = str
                    }
                }
                for font in dynamicFontSizes {
                    itemFontSize = font
                    let maxWidth = maxLengthItem.getRectSizeOfFont(font, constraintSize: CGSize(width:ViewHelper.screenWidth(), height: ViewHelper.screenHeight())).width
                    if maxWidth < ViewHelper.screenWidth() - VS.margin15 {
                        break
                    }
                }
            }
            
            // render core
            pickerView.removeFromSuperview()
            pickerContainer.removeFromSuperview()
            pickerView.delegate = self
            pickerView.dataSource = self
            pickerView.frame = CGRect(x: 0, y: -15, width: ViewHelper.screenWidth(), height: 216)
            pickerContainer.frame = CGRect(x: 0, y: 0, width: ViewHelper.screenWidth(), height: 186)
            pickerContainer.clipsToBounds = true
            pickerContainer.addSubview(pickerView)
            
            self.addSubview(pickerContainer)
        }
        
        func setDefaultValue(_ defaultValue : ((_ item:T)->Bool)?) {
            if defaultValue != nil {
                if let index = self.data.index(where: defaultValue!) {
                    pickedValue = data[index]
                    pickerView.selectRow(Int(index), inComponent: 0, animated: false)
                    return
                }
            }
            if pickedValue == nil && data.count > 0 {
                pickedValue = data.first
            }
        }
    }
    

}

/// 日期选择工具
open class DatePickerTools: PickerTools {
  
    static public func selectDateActionSheet(_ defaultValue : Date? = Date(), isWithTime: Bool = false, setting : ((_ calendar:UIDatePicker)->Void)? = nil, actionSelected : @escaping (_:Date)->Void) {
        let actionSheet = GAActionSheet()
        
        let picker = DatePickerActionSheetView()
        picker.frame = CGRect(x: 0, y: 0, width: ViewHelper.screenWidth(), height: 236)
        picker.backgroundColor = UIColor.white
        picker.confirmButtonAction = actionSelected
        let weakRefer = WeakReferenceWrapper(refer: actionSheet)
        picker.cancelButtonAction = {
            if let sheet: GAActionSheet = weakRefer.refer() {
                sheet.dismiss()
            }
        }
        picker.isWithTime = isWithTime
        picker.render(defaultValue, setting: setting)
        
        actionSheet.contentView = picker
        actionSheet.show()
        picker.window?.endEditing(true)
    }

    
    public class DatePickerActionSheetView : EmptyPickActionSheetView<Date> {
        
        var pickerView : UIDatePicker!
        var pickerContainer = UIView()
        var isWithTime = false
        
        override public var  pickedValue : Date? {
            get { return self.pickerView?.date }
            set { if newValue != nil { self.pickerView?.date = newValue! } }
        }
        
        override public func render() {
            render(Date())
        }
        
        func render(_ defaultValue : Date?, setting : ((_ calendar : UIDatePicker)->Void)? = nil) {
            super.render()
            
            pickerContainer.removeFromSuperview()
            if pickerView == nil {
                pickerView = UIDatePicker(frame: CGRect.zero)
                pickerView.datePickerMode = isWithTime ? .dateAndTime : .date
                pickerView.minimumDate = "1990/1/1".toDate()
                pickerView.maximumDate = "2999/1/1".toDate()
                pickerView.timeZone = TimeZone(identifier: kTimeZone)
                pickerView.frame = CGRect(x: 0, y: -15, width: ViewHelper.screenWidth(), height: 216)
                pickerContainer.frame = CGRect(x: 0, y: 0, width: ViewHelper.screenWidth(), height: 186)
                pickerContainer.clipsToBounds = true
                pickerContainer.addSubview(pickerView)
            }
            setting?(pickerView)
            pickedValue = defaultValue ?? Date()
            self.addSubview(pickerContainer)
        }
    }
}


public class DoubleComponentPickerActionSheetView<T, TKey : Hashable> : DatePickerTools.PickerActionSheetView<T> {
    
    public init(key : @escaping (_:T) -> TKey) {
        groupSelector = key
        super.init()
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    var groupSelector : (_:T) -> TKey
    fileprivate var groups = [TKey]()
    fileprivate var groupedData = [TKey:[T]]()
    fileprivate var selectedType : TKey?
    var firstComponentName : String? = ""
    var secondComponentName : String? = ""
    var keyDisplay : (_:TKey)->String = { x in x as? String ?? "" }
    override var data : [T]{
        didSet{
            groupedData = self.data.groupBy(groupSelector)
//            groups = self.groupedData.map({ $0.0 })
            for e in self.data {
                let key = groupSelector(e)
                if !groups.contains(key) {
                    groups.append(key)
                }
            }
            selectedType = groups.first
        }
    }
    
    
    override public func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 2
    }
    
    override public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        switch component {
        case 0 : return groups.count
        case 1 : return selectedType == nil ? 0 :  groupedData[selectedType!]?.count ?? 0
        default : return 0
        }
    }
    
    override public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        switch component {
        case 0 : return self.firstComponentName
        case 1 : return self.secondComponentName
        default : return nil
        }
    }
    
    override public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        switch component {
        case 0:
            if row < groupedData.count {
                selectedType = groups[row]
                //当选择房型后没有触动房间的滚轮的时候 pickValue 是没有值的 给它默认的附上初始值
                let rooms =  groupedData[selectedType!] ?? [T]()
                self.pickedValue = rooms.first
                
                if rooms.count != 0 {
                self.pickerView.selectRow(0, inComponent: 1, animated: false)
                }
                pickerView.reloadComponent(1)
               // self.pickerView.selectRow(0, inComponent: 1, animated: false)

            }
        case 1:
            if selectedType == nil { break }
            let rooms =  groupedData[selectedType!] ?? [T]()
            if row < rooms.count {
                self.pickedValue = rooms[row]
            }
        default : break
        }
    }
    
    override public func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        var name = ""
        switch component {
        case 0 :
            if row < groups.count { name = keyDisplay(groups[row]) }
        case 1 :
            if selectedType == nil { break }
            let rooms = groupedData[selectedType!] ?? [T]()
            if row < rooms.count { name = display(rooms[row]) }
        default: break
        }
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 16)
        label.text = name
        label.textAlignment = .center
        label.lineBreakMode = .byTruncatingMiddle
        return label
    }
    
    override func setDefaultValue(_ defaultValue: ((_ item: T) -> Bool)?) {
        if (defaultValue != nil) {
            for (type,groupdata) in groupedData {
                if let index = groupdata.index(where: { x in defaultValue!(x) }) {
                    selectedType = type
                    pickedValue = groupdata[index]
                    self.pickerView.selectRow(Int(self.groups.index(of: type)!), inComponent: 0, animated: false)
                    self.pickerView.reloadComponent(1)
                    self.pickerView.selectRow(index, inComponent: 1, animated: false)
                  //  self.pickerView.reloadAllComponents()
                    return
                }
            }
        }
        if pickedValue == nil {
            if let localType = selectedType ?? groups.first {
                selectedType = localType
                if let localGroup = self.groupedData[localType]{
                    if localGroup.count > 0 {
                        pickedValue = localGroup.first
                    }
                }
            }
        }
    }
}
